'''
Created on Feb 26, 2010

@author: mkiyer
'''
import os
import re
import logging

import xml.etree.cElementTree as etree

class PipelineConfig(object):
    
    def __init__(self, xml_file):        
        # remember xml file
        self.xml_file = xml_file
        # fill these variables with values from the xml
        self.parse_xml(xml_file)

    def __str__(self):
        s = map(str,[self.sdbi_path,
                     self.qc_filter,
                     self.cuffcompare_path,
                     self.known_genes_path,
                     self.genome_version,
                     self.interenic_recurrence,
                     self.intergenic_dist])
        return '\t'.join(s)

    def _find_file(self, path, default_path):
        if os.path.exists(path):
            return os.path.abspath(path)        
        hacked_path = self._fix_path(path)
        if os.path.exists(hacked_path):
            return os.path.abspath(hacked_path)
        # prepend the prefix and repeat search
        joined_path = os.path.join(default_path, path)        
        if os.path.exists(joined_path):
            return os.path.abspath(joined_path)
        hacked_path = self._fix_path(joined_path)
        if os.path.exists(hacked_path):
            return os.path.abspath(hacked_path)
        raise OSError("File not found")
    
    def _fix_path(self, path):
        # hacked garbage
        hacked_path = re.sub('archive11', 'data2', path, count=1)
        if os.path.exists(hacked_path):
            return hacked_path
        hacked_path = re.sub('data2', 'archive11', path, count=1)
        if os.path.exists(hacked_path):
            return hacked_path        
        return path

    def _parse_yesno_text(self, s):
        return True if s.upper() == 'YES' else False

    def parse_xml(self, xml_file):
        tree = etree.parse(xml_file)
        root = tree.getroot()    
        assert root.tag == 'chipseq'
        # databases
        self.databases = {}
        dbelem = root.find('databases')
        for elem in dbelem.findall('db'):
            dbname = elem.get('name')
            connect = elem.findtext('connect')
            schema = elem.findtext('schema')
            self.databases[dbname] = (connect, schema)        
        # sample pools
        elem = root.find('sample_pools')
        self.sample_pools_dir = elem.findtext('dir')
        self.sample_pools_force = self._parse_yesno_text(elem.findtext('force'))
        self.alignment_dir = elem.findtext('alignment_dir')
        self.make_norm_bigwig = self._parse_yesno_text(elem.findtext('make_normalized_bigwig'))
        self.make_raw_bigwig = self._parse_yesno_text(elem.findtext('make_raw_bigwig'))
        self.cdna_fragment_length = int(elem.findtext('cdna_fragment_length'))
        # analysis
        elem = root.find('analysis')
        self.analysis_dir = elem.findtext('dir')
        self.analysis_force = self._parse_yesno_text(elem.findtext('force'))
        # general options
        self.db = root.findtext('db')
        self.output_dir = root.findtext('output_dir')
        self.genome_version = root.findtext('genome_version')
        # ucsc
        elem = root.find('ucsc')        
        self.ucsc_bin_dir = elem.findtext('bin')

#        # general options
#        output_dir = root.findtext('output_dir')
#        self.output_dir = output_dir if output_dir != None else None        
#        data_dir = root.findtext('data_dir')
#        self.data_dir = data_dir
#        self.genome_version = root.findtext('genome_version')        
#        # sample tags
#        elem = root.find('samples')
#        self.sample_file = self._find_file(elem.get('file'), data_dir)
#        logging.debug("Sample file: %s" % self.sample_file)
#        self.sample_db_file = self._find_file(elem.findtext('db'), data_dir)
#        logging.debug("Sample DB file: %s" % self.sample_db_file)        
#        self.sample_qc_filter = True if elem.findtext('qc_filter') == "True" else False
#        logging.debug("Sample QC filter = %s" % str(self.sample_qc_filter))
#        # cuffcompare tags
#        elem = root.find('cuffcompare')
#        self.tophat_path = self._fix_path(elem.findtext('tophat_path'))
#        logging.debug("TopHat path: %s" % self.tophat_path)        
#        self.cuffcompare_output_path = self._fix_path(elem.findtext('output_path'))
#        logging.debug("Cuffcompare path: %s" % self.cuffcompare_output_path)        
#        self.cuffcompare_executable = self._find_file(elem.findtext('executable'), data_dir)
#        logging.debug("Cuffcompare binary: %s" % self.cuffcompare_executable)        
#        self.cuffcompare_ref_gtf = self._find_file(elem.findtext('ref_gtf'), data_dir)
#        logging.debug("Cuffcompare reference GTF: %s" % self.cuffcompare_ref_gtf)        
#
#        # clustering tags
#        elem = root.find('cluster')        
#        self.cluster_min_exons = int(elem.findtext('min_exons'))
#        elem2 = elem.find('intergenic')        
#        self.intergenic_filter = True if (elem2.get('filter') == "True") else False
#        self.intergenic_dist = int(elem2.findtext('dist'))
#        self.intergenic_recurrence = int(elem2.findtext('recurrence'))
#        self.known_genes_file = self._find_file(elem2.findtext('known_genes_file'), data_dir)
#
#        # expression tags
#        elem = root.find('expression')
#        self.phdb_path = elem.findtext('phdb_path')
#        self.track_name = elem.findtext('track_name')
#
#        # correlation tags
#        elem = root.find('correlate')
#        self.correlate_min_corr = float(elem.findtext('min_corr'))
#        logging.debug("Minimum correlation coefficient: %f" % self.correlate_min_corr)
#        self.correlate_max_pval = float(elem.findtext('max_pval'))
#        logging.debug("Correlation p-value threshold: %f" % self.correlate_max_pval)
#        self.correlate_max_dist = int(elem.findtext('max_dist'))
#        logging.debug("Correlation distance threshold: %f" % self.correlate_max_dist)
#
#        # filtering tags
#        elem = root.find('filter')        
#        self.median_filter = True if (elem.find('min_median_rpkm').get('apply') == "True") else False
#        self.min_median_rpkm = float(elem.findtext('min_median_rpkm'))
#        self.rpkm_filter = True if (elem.find('min_rpkm').get('apply') == "True") else False
#        self.min_rpkm = float(elem.findtext('min_rpkm'))
#        self.recurrence_filter = True if (elem.find('min_recurrence').get('apply') == "True") else False
#        self.min_recurrence = int(elem.findtext('min_recurrence'))
#        self.size_filter = True if (elem.find('min_size').get('apply') == "True") else False
#        self.min_size = int(elem.findtext('min_size'))
#        elem2 = elem.find('uniqueness')
#        self.uniqueness_filter = True if (elem2.get('apply') == "True") else False
#        self.uniqueness_min_neglogp = float(elem2.findtext('min_neglogp'))
#        self.uniqueness_min_unique_stretch = float(elem2.findtext('min_unique_stretch'))

if __name__ == '__main__':
    import sys
    p = PipelineConfig()
    p.parse_xml(sys.argv[1])
    print p